package com.drondea.testclient.panel;

import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import com.drondea.sms.conf.cmpp.CmppClientSocketConfig;
import com.drondea.sms.session.cmpp.CmppClientSessionManager;
import com.drondea.sms.type.CmppConstants;
import com.drondea.testclient.handler.cmpp.CmppClientCustomHandler;
import com.drondea.testclient.model.AppConfig;
import com.drondea.testclient.model.Model;
import com.drondea.testclient.model.User;
import com.drondea.testclient.service.AbstractTcpService;
import com.drondea.testclient.service.CmppService;
import com.drondea.testclient.service.ConfigService;
import com.drondea.testclient.service.provider.CmppClientMessageProvider;
import com.drondea.testclient.util.CommonThreadPoolFactory;
import com.drondea.testclient.util.ProtocolType;
import com.drondea.testclient.util.counter.CmppAtomicUtil;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import java.util.concurrent.TimeUnit;


/**
 * CMPP协议面板
 *
 * @author shd
 */

@Slf4j
public class CmppPanel extends AbstractTcpPanel {

    private static final CmppPanel CMPP_PANEL = new CmppPanel();

    private CmppPanel() {
    }

    public static CmppPanel getInstance() {
        return CMPP_PANEL;
    }

    /**
     * CMPP协议特有属性
     */
    protected JLabel serviceIdLabel;
    public JTextField serviceIdTextField;
    protected JLabel msgSrcLabel;
    public JTextField msgSrcTextField;
    

    @Override
    public void init(int width, int height) {
        user = ConfigService.findBean(Model.CT_USER.getCode(), "CMPP", User.class);
        log.info("cmpp user : {}", user);

        CronUtil.schedule("0/1 * * * * ? ", (Runnable) () -> {
            long nowSendCount = CmppAtomicUtil.SEND_COUNT.get();
            submitSpeedLabel.setText(StrUtil.format("发送速度: {}/s", (nowSendCount - lastSendCount)));
            lastSendCount = nowSendCount;
            long nowResponseCount = CmppAtomicUtil.RESPONSE_COUNT.get();
            responseSpeedLabel.setText(StrUtil.format("响应速度: {}/s", (nowResponseCount - lastResponseCount)));
            lastResponseCount = nowResponseCount;
            long nowReportCount = CmppAtomicUtil.REPORT_COUNT.get();
            reportSpeedLabel.setText(StrUtil.format("回执速度: {}/s", (nowReportCount - lastReportCount)));
            lastReportCount = nowReportCount;
        });
        super.init(width, height);
    }

    @Override
    protected void initText() {
        super.initText();

        serviceIdLabel = new JLabel("Service_Id");
        serviceIdLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        panel.add(serviceIdLabel);
        serviceIdTextField = new JTextField();
        serviceIdTextField.setText("");
        serviceIdTextField.setColumns(10);
        panel.add(serviceIdTextField);
        
        msgSrcLabel = new JLabel("Msg_src");
        msgSrcLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        panel.add(msgSrcLabel);
        msgSrcTextField = new JTextField();
        msgSrcTextField.setText("");
        msgSrcTextField.setColumns(10);
        panel.add(msgSrcTextField);
    }

    @Override
    public void initComponentBounds(int width, int height) {
        super.initComponentBounds(width, height);
        
        serviceIdLabel.setBounds((int) (width * 0.03), (int) (height * 0.61), (int) (width * 0.07), (int) (height * 0.03));
        serviceIdTextField.setBounds((int) (width * 0.11), (int) (height * 0.61), (int) (width * 0.15), (int) (height * 0.04));
        msgSrcLabel.setBounds((int) (width * 0.03), (int) (height * 0.69), (int) (width * 0.07), (int) (height * 0.03));
        msgSrcTextField.setBounds((int) (width * 0.11), (int) (height * 0.69), (int) (width * 0.15), (int) (height * 0.04));
    }

    @Override
    protected void connect() {
        // 保存连接的配置信息
        saveConfigInfo();

        isCanSend = true;

        CmppClientSocketConfig socketConfig = new CmppClientSocketConfig(userNameTextField.getText(),
                10 * 1000, 16, ipTextField.getText(), Integer.parseInt(portTextField.getText()));
        socketConfig.setChannelSize(Integer.parseInt(connectCountTextField.getText()));
        socketConfig.setUserName(userNameTextField.getText());
        socketConfig.setPassword(passwordTextField.getText());
        socketConfig.setVersion(CmppConstants.VERSION_20);

        // 限速 条/s
        socketConfig.setQpsLimit(Integer.parseInt(speedTextField.getText()));
        // 开启超时监控,设置监控间隔时间，这个值最好是RequestExpiryTimeout的1/2
        socketConfig.setWindowMonitorInterval(10 * 1000);
        // 设置响应超时时间
        socketConfig.setRequestExpiryTimeout(20 * 1000);
        socketConfig.setServiceId("1");
        AppConfig appConfig = ConfigService.findBean(Model.APP_CONFIG.getCode(), "APP", AppConfig.class);
        socketConfig.setWindowSize(appConfig.getWindowSize() == 0 ? 10000 : appConfig.getWindowSize());
        log.info("cmpp window size : {}", socketConfig.getWindowSize());

        CmppClientCustomHandler cmppCustomHandler = new CmppClientCustomHandler();
        sessionManager = new CmppClientSessionManager(socketConfig, cmppCustomHandler);
        sessionManager.setMessageProvider(new CmppClientMessageProvider());
        //创建链接
        sessionManager.doOpen();
        sessionManager.doCheckSessions();
    }

    @Override
    public ProtocolType getProtocol() {
        return ProtocolType.CMPP;
    }

    @Override
    protected AbstractTcpService getService() {
        return CmppService.getInstance();
    }

    @Override
    protected void counterReset() {
        CmppAtomicUtil.clear();
    }

    @Override
    protected void loopRefreshPanelData(int delay) {
        CommonThreadPoolFactory.getInstance().getScheduleExecutor().schedule(() -> {
            sendCountLabel.setText(StrUtil.format("发送数量: {}", CmppAtomicUtil.SEND_COUNT.get()));
            
            loopRefreshPanelData(delay);
        }, delay, TimeUnit.MILLISECONDS);
    }

    @Override
    protected void saveConfigInfo() {
        User user = new User("CMPP", ipTextField.getText(), Integer.parseInt(portTextField.getText()), userNameTextField.getText(),
                passwordTextField.getText(), Integer.parseInt(connectCountTextField.getText()), Integer.parseInt(speedTextField.getText()));
        ConfigService.update(Model.CT_USER.getCode(), "CMPP", user);
    }


}